#ifndef TIEC_UTIL_H
#define TIEC_UTIL_H

#include "macro.h"
#include "data.h"
#include <locale>

#include "foundation.h"

namespace NS_TIEC {

  class TimeUtil {
  public:
    /// 获取当前毫秒时间戳
    /// \return 毫秒时间戳
    static Int64 milliTime();

    /// 获取当前微秒时间戳
    /// \return 微秒时间戳
    static Int64 microTime();

    /// 获取当前纳秒时间戳
    /// \return 纳秒时间戳
    static Int64 nanoTime();
  };

  /// 汉字拼音信息
  struct HanziPinyin {
    /// 所有首拼（包含多音字读音）
    List<WString> firsts;
    /// 所有全拼（包含多音字读音）
    List<WString> fulls;
  };

  class PinyinUtil {
  public:
    /// 获取汉字所有拼音信息（包含所有多音字全拼首拼）
    /// @param in_str 汉字
    /// @return 汉字拼音信息
    static HanziPinyin getHanziPinyin(const WString& in_str);

    /// 获取汉字首拼
    /// @param in_str 汉字
    static WString getHanziFirstPinyin(const WString& in_str);

    /// 获取汉字全拼
    /// @param in_str 汉字
    static WString getHanziFullPinyin(const WString& in_str);

    /// 获取汉字全拼（小驼峰形式）
    /// @param in_str
    static WString getHanziFullPinyinLowerCamel(const WString& in_str);

    /// 获取汉字全拼（大驼峰形式）
    /// @param in_str 汉字
    static WString getHanziFullPinyinUpperCamel(const WString& in_str);
  };

  /// 计算多个值的哈希值
  template<typename... Args>
  size_t multiHash(const Args&... args) {
    size_t seed = 0;
    ((seed = seed ^ (std::hash<std::decay_t<Args>>{}(args) + 0x9e3779b9 + (seed << 6) + (seed >> 2))), ...);
    return seed;
  }

  /// String转换为WString
  /// \param s String内容
  /// \return
  WString toWString(const String& s);

  /// 字节集转换为WString
  /// \param bytes 字节集
  /// \return
  WString toWString(const ByteArray& bytes);

  /// WString转换为String
  /// \param ws WString内容
  /// \return
  String toString(const WString& ws);

  /// 将宽文本转换为C风格字符串（内存安全）
  /// @param ws 宽文本
  UPTR<const char[]> toCString(const WString& ws);

  /// 字节集转换为String
  /// \param bytes 字节集
  /// \return
  String toString(const ByteArray& bytes);

  /// 整数转换为String
  /// \param n 整数
  /// \return
  String toString(Int64 n);

  /// float转换为String
  /// \param n 整数
  /// \return
  String toString(float n);

  /// double转换为String
  /// \param n 整数
  /// \return
  String toString(double n);

  /// String转int32
  /// \param s 字符串
  /// \return
  Int32 toInt32(const String& s);

  /// 16进制String转int32
  /// \param s 字符串
  /// \return
  Int32 hexToInt32(const String& s);

  /// 8进制String转int32
  /// \param s 字符串
  /// \return
  Int32 octToInt32(const String& s);

  /// String转int64
  /// \param s 字符串
  /// \return
  Int64 toInt64(const String& s);

  /// 16进制String转int64
  /// \param s 字符串
  /// \return
  Int64 hexToInt64(const String& s);

  /// 8进制String转int64
  /// \param s 字符串
  /// \return
  Int64 octToInt64(const String& s);

  /// String转float
  /// \param s 字符串
  /// \return
  float toFloat(const String& s);

  /// String转double
  /// \param s 字符串
  /// \return
  double toDouble(const String& s);

  /// 接受va_list作为参数进行格式化
  /// @param format 格式
  /// @param args 参数
  /// @return 格式化之后的文本
  String vFormatString(const char* format, va_list args);

  /// 格式化字符串
  /// \param format 格式
  /// \param ... 替换参数
  /// \return 格式化之后的文本
  String formatString(const char* format, ...);

  /// 去首尾空
  /// \param str 要去除首尾空的文本
  String trim(const String& str);

  /// 处理转义字符
  String unescape(const String& str);
}

#endif //TIEC_UTIL_H
